﻿#include <gtk/gtk.h>
#include <glib/gprintf.h>

static void append_text(GtkTextView *text_view, const gchar* text)
{
    GtkTextBuffer *text_buffer = gtk_text_view_get_buffer(text_view);
    GtkTextIter itr;
    gtk_text_buffer_get_end_iter(text_buffer, &itr);
    gtk_text_buffer_insert(text_buffer, &itr, text, -1);

}
static void print_styles(GtkWidget *widget, GtkWidget *target)
{
    GtkTextView *text_view = GTK_TEXT_VIEW(widget);
    append_text(text_view, "style list:\n");

    gchar text[256];

    GtkStyleContext *style_context =  gtk_widget_get_style_context(target);

    {        
        const GtkWidgetPath *wp = gtk_style_context_get_path(style_context);
        gchar* path = gtk_widget_path_to_string(wp);
        g_sprintf(text, "widgetPath:    %s\n", path);
        g_free(path);
        append_text(text_view, text);
    }


    {
        GtkStateFlags state = gtk_style_context_get_state(style_context);
        g_sprintf(text, "gtkStateFlags:    0x%x\n\t(GTK_STATE_FLAG_NORMAL=%d, _ACTIVE=%d, _PRELIGHT=%d, _SELECTED=%d, _FOCUSED=%d, _DIR_LTR=%d)\n"
                    , state
                    , GTK_STATE_FLAG_NORMAL
                    , GTK_STATE_FLAG_ACTIVE
                    , GTK_STATE_FLAG_PRELIGHT
                    , GTK_STATE_FLAG_SELECTED
                    , GTK_STATE_FLAG_FOCUSED
                    , GTK_STATE_FLAG_DIR_LTR
                    );
        append_text(text_view, text);
    }
            //get border
    {
        GtkStateFlags state = GTK_STATE_FLAG_DIR_LTR;//GTK_STATE_FLAG_NORMAL;
        GtkBorder border;
        gtk_style_context_get_border(style_context, state, &border);
        g_sprintf(text, "gtkBorder:    %d,%d,%d,%d(left,right,top,bottom)\n"
                    , border.left, border.right
                    , border.top, border.bottom);
        append_text(text_view, text);

    }

            //get padding
    {
        GtkStateFlags state = GTK_STATE_FLAG_DIR_LTR;//GTK_STATE_FLAG_NORMAL;
        GtkBorder padding;
        gtk_style_context_get_padding(style_context, state, &padding);
        g_sprintf(text, "gtkPadding:    %d,%d,%d,%d(left,right,top,bottom)\n"
                    , padding.left, padding.right
                    , padding.top, padding.bottom);
        append_text(text_view, text);

    }

            //get margin
    {
        GtkStateFlags state = GTK_STATE_FLAG_DIR_LTR;//GTK_STATE_FLAG_NORMAL;
        GtkBorder margin;
        gtk_style_context_get_margin(style_context, state, &margin);
        g_sprintf(text, "gtkMargin:    %d,%d,%d,%d(left,right,top,bottom)\n"
                    , margin.left, margin.right
                    , margin.top, margin.bottom);
        append_text(text_view, text);

    }

            //get color
    {
        GtkStateFlags state = GTK_STATE_FLAG_DIR_LTR;// | GTK_STATE_FLAG_NORMAL;
        GdkRGBA color;
        gtk_style_context_get_color(style_context, state, &color);
        g_sprintf(text, "color:    %s\n", gdk_rgba_to_string(&color));
        append_text(text_view, text);
    }


            //get bgcolor
    {
        GtkStateFlags state = GTK_STATE_FLAG_DIR_LTR;// | GTK_STATE_FLAG_NORMAL;
        GdkRGBA color;
G_GNUC_BEGIN_IGNORE_DEPRECATIONS        
        gtk_style_context_get_background_color(style_context, state, &color);
G_GNUC_END_IGNORE_DEPRECATIONS        
        g_sprintf(text, "bgcolor:    %s\n", gdk_rgba_to_string(&color));
        append_text(text_view, text);
    }

            //get bordercolor
    {
        GtkStateFlags state = GTK_STATE_FLAG_DIR_LTR;// | GTK_STATE_FLAG_NORMAL;
        GdkRGBA color;
G_GNUC_BEGIN_IGNORE_DEPRECATIONS        
        gtk_style_context_get_border_color(style_context, state, &color);
G_GNUC_END_IGNORE_DEPRECATIONS        
        g_sprintf(text, "bordercolor:    %s\n", gdk_rgba_to_string(&color));
        append_text(text_view, text);
    }


            //get classes
    {
        GtkStateFlags state = GTK_STATE_FLAG_DIR_LTR;// | GTK_STATE_FLAG_NORMAL;
        GList *clazzes;
        clazzes = gtk_style_context_list_classes(style_context);

        g_sprintf(text, "classes:    \n");
        append_text(text_view, text);

        for(GList *p= clazzes; p!= NULL; p = p->next)
        {
            g_sprintf(text, "\t\t%s\n", (gchar*)p->data);
            append_text(text_view, text);
        }

        g_list_free(clazzes);           //zf, 此处node data不需释放
    }

            //get scale
    {
        GtkStateFlags state = GTK_STATE_FLAG_DIR_LTR;// | GTK_STATE_FLAG_NORMAL;
        g_sprintf(text, "scale:    %d\n", gtk_style_context_get_scale(style_context));
        append_text(text_view, text);
    }

            //get context string.
    {
        GtkStateFlags state = GTK_STATE_FLAG_DIR_LTR;// | GTK_STATE_FLAG_NORMAL;

        
        gchar *s = gtk_style_context_to_string(style_context, GTK_STYLE_CONTEXT_PRINT_RECURSE|GTK_STYLE_CONTEXT_PRINT_SHOW_STYLE);

        g_sprintf(text, "context str:    %s\n", s);
        append_text(text_view, text);

        g_free(s);
    }

}

static void activate(GtkApplication *app, gpointer user_data)
{
    GtkWidget *window;
    GtkWidget *box;
    GtkWidget *widget;
    GtkWidget *button;

    window = gtk_application_window_new(app);
    gtk_window_set_title(GTK_WINDOW(window), "a12_styleContext");
    gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);

    
    
    box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    gtk_container_add(GTK_CONTAINER(window), box);

    button = gtk_button_new_with_label("button");
    gtk_box_pack_start(GTK_BOX(box), button,FALSE, FALSE, 0);

    widget = gtk_text_view_new();
    gtk_text_view_set_editable(GTK_TEXT_VIEW(widget), FALSE);
    gtk_box_pack_start(GTK_BOX(box), widget,TRUE, TRUE, 0);

    gtk_widget_show_all(GTK_WIDGET(window));

    print_styles(widget, button);
}

int main(int argc, char** argv)
{
    GtkApplication *app;
    int status;

    app = gtk_application_new("com.gitee.zcatt.gtk.sample.a12_styleContext", G_APPLICATION_FLAGS_NONE);
    g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
    status = g_application_run(G_APPLICATION(app),argc, argv);
    g_assert_true((G_OBJECT(app)->ref_count == 1));
    g_object_unref(app);

    return status;
}
